package com.corewillsoft.fireflies.storage;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import android.content.Context;

import com.corewillsoft.fireflies.gameobjects.obstacles.Obstacle;
import com.corewillsoft.fireflies.gameobjects.obstacles.Obstacle.ObstacleParameterType;
import com.corewillsoft.fireflies.gameobjects.obstacles.Obstacle.ObstacleParametersList;
import com.corewillsoft.fireflies.gameobjects.obstacles.trajectories.Trajectory.TrajectoryType;
import com.corewillsoft.fireflies.storage.objects.BaseGameLevel;
import com.corewillsoft.fireflies.storage.objects.MapLevel;
import com.corewillsoft.fireflies.storage.objects.StartGameLevel;

public class DatabaseInitializer {

	private final DbManager dbManager;

	public DatabaseInitializer(Context context) {
		this.dbManager = new DbManager();
	}

	/**
	 * Initializes data for {@link MapLevel} and {@link BaseGameLevel} objects and saves them to database
	 */
	public void initDatabase() {
		initMapLevels();
		initGameLevels();
	}

	private void initMapLevels() {
		addMapLevel0();
		addMapLevel1();
		addMapLevel2();
		addMapLevel3();
	}

	private void addMapLevel0() {
		int level = 0;
		MapLevel mapLevel = new MapLevel(level, 5, 5, 90, 90, "firefly_image.jpg");
		dbManager.addMapLevel(mapLevel);
	}

	private void addMapLevel1() {
		int level = 1;
		MapLevel mapLevel = new MapLevel(level, 100, 5, 90, 90, "firefly_image.jpg");
		dbManager.addMapLevel(mapLevel);
	}

	private void addMapLevel2() {
		int level = 2;
		MapLevel mapLevel = new MapLevel(level, 195, 5, 90, 90, "firefly_image.jpg");
		dbManager.addMapLevel(mapLevel);
	}

	private void addMapLevel3() {
		int level = 3;
		MapLevel mapLevel = new MapLevel(level, 290, 5, 90, 90,  "firefly_image.jpg");
		dbManager.addMapLevel(mapLevel);
	}

	private void initGameLevels() {
		addGameLevel0();
		addGameLevel1();
		addGameLevel2();
		addGameLevel3();
	}

	private void addGameLevel0() {
		int level = 0;

		Integer[] fireflyIds = new Integer[] { 0, 0, 0, 0, 1, 1, 1, 1 };
		Integer[] fireflyX = new Integer[] { 110, 250, 370, 280, 150, 180, 270, 410 };
		Integer[] fireflyY = new Integer[] { 180, 170, 260, 350, 440, 530, 220, 410 };
		Integer[] portalIds = new Integer[] { 0, 1 };
		Integer[] portalX = new Integer[] { 0, 380 };
		Integer[] portalY = new Integer[] { 0, 620 };
		Integer[] obstacleIds = new Integer[] { Obstacle.ObstacleType.WALL.ordinal(),
			Obstacle.ObstacleType.FROG.ordinal(),
			Obstacle.ObstacleType.HORNET.ordinal(),
			Obstacle.ObstacleType.HORNET.ordinal(),
			Obstacle.ObstacleType.HORNET.ordinal(),
			Obstacle.ObstacleType.FAN.ordinal()
		};
		Integer[] obstacleX = new Integer[] { 75, 220, 150, 300, 250, 0 };
		Integer[] obstacleY = new Integer[] { 100, 660, 420, 80, 80, 240 };

		//TODO @kshpachenko simplify addition of obstacles' parameters here by creating some utility methods for this
		List<Obstacle.ObstacleParameters> obstaclesParameters = new ArrayList<Obstacle.ObstacleParameters>();

		Obstacle.ObstacleParameters obstacle1Params = new Obstacle.ObstacleParameters(){{
			put(ObstacleParameterType.SIZE, new ObstacleParametersList(){{
				add(120f);
				add(40f);
			}});
		}};

		Obstacle.ObstacleParameters obstacle2Params = new Obstacle.ObstacleParameters(){{
		}};

		Obstacle.ObstacleParameters obstacle3Params = new Obstacle.ObstacleParameters(){{
			put(ObstacleParameterType.TRAJECTORY, new ObstacleParametersList(){{
				add((float) TrajectoryType.CIRCULAR.ordinal());
				add(80f);
				add(400f);
				add(72.8f);
			}});
			put(ObstacleParameterType.SIZE, new ObstacleParametersList(){{
				add(30f);
				add(20f);
			}});
		}};

		Obstacle.ObstacleParameters obstacle4Params = new Obstacle.ObstacleParameters(){{
			put(ObstacleParameterType.TRAJECTORY, new ObstacleParametersList(){{
				add((float) TrajectoryType.RECTANGULAR.ordinal());
				add(190f);	add(20f);
				add(300f);	add(80f);
			}});
		}};

		Obstacle.ObstacleParameters obstacle5Params = new Obstacle.ObstacleParameters(){{
			put(ObstacleParameterType.TRAJECTORY, new ObstacleParametersList(){{
				add((float) TrajectoryType.POLYLINE.ordinal());
				add(0f);
				add(250f);	add(80f);
				add(350f);	add(150f);
				add(300f);	add(400f);
				add(200f);	add(300f);
				add(60f);	add(500f);
			}});
		}};

		Obstacle.ObstacleParameters obstacle6Params = new Obstacle.ObstacleParameters(){{
		}};

		obstaclesParameters.add(obstacle1Params);
		obstaclesParameters.add(obstacle2Params);
		obstaclesParameters.add(obstacle3Params);
		obstaclesParameters.add(obstacle4Params);
		obstaclesParameters.add(obstacle5Params);
		obstaclesParameters.add(obstacle6Params);

		BaseGameLevel gameLevel = new StartGameLevel();
		gameLevel.setLevel(level);
		gameLevel.setFireflyIds(Arrays.asList(fireflyIds));
		gameLevel.setFireflyX(Arrays.asList(fireflyX));
		gameLevel.setFireflyY(Arrays.asList(fireflyY));
		gameLevel.setPortalIds(Arrays.asList(portalIds));
		gameLevel.setPortalX(Arrays.asList(portalX));
		gameLevel.setPortalY(Arrays.asList(portalY));
		gameLevel.setObstacleIds(Arrays.asList(obstacleIds));
		gameLevel.setObstacleX(Arrays.asList(obstacleX));
		gameLevel.setObstacleY(Arrays.asList(obstacleY));
		gameLevel.setObstaclesParameters(obstaclesParameters);
		dbManager.addGameLevel(gameLevel);
	}

	private void addGameLevel1() {
		int level = 1;

		Integer[] fireflyIds = new Integer[] { 0, 0, 0, 0, 1, 1, 1, 1 };
		Integer[] fireflyX = new Integer[] { 110, 250, 370, 280, 150, 180, 270,
				310 };
		Integer[] fireflyY = new Integer[] { 180, 170, 260, 350, 440, 530, 220,
				410 };
		Integer[] portalIds = new Integer[] { 0, 1 };
		Integer[] portalX = new Integer[] { 0, 380 };
		Integer[] portalY = new Integer[] { 0, 620 };
		Integer[] obstacleIds = new Integer[] { 3 };
		Integer[] obstacleX = new Integer[] { 150 };
		Integer[] obstacleY = new Integer[] { 200 };

		BaseGameLevel gameLevel = new StartGameLevel();
		gameLevel.setLevel(level);
		gameLevel.setFireflyIds(Arrays.asList(fireflyIds));
		gameLevel.setFireflyX(Arrays.asList(fireflyX));
		gameLevel.setFireflyY(Arrays.asList(fireflyY));
		gameLevel.setPortalIds(Arrays.asList(portalIds));
		gameLevel.setPortalX(Arrays.asList(portalX));
		gameLevel.setPortalY(Arrays.asList(portalY));
		gameLevel.setObstacleIds(Arrays.asList(obstacleIds));
		gameLevel.setObstacleX(Arrays.asList(obstacleX));
		gameLevel.setObstacleY(Arrays.asList(obstacleY));

		dbManager.addGameLevel(gameLevel);
	}

	private void addGameLevel2() {
		int level = 2;

		Integer[] fireflyIds = new Integer[] { 0, 0, 0, 0, 1, 1, 1, 1 };
		Integer[] fireflyX = new Integer[] { 110, 250, 370, 280, 150, 180, 270,
				310 };
		Integer[] fireflyY = new Integer[] { 180, 170, 260, 350, 440, 530, 220,
				410 };
		Integer[] portalIds = new Integer[] { 0, 1 };
		Integer[] portalX = new Integer[] { 0, 380 };
		Integer[] portalY = new Integer[] { 0, 620 };
		Integer[] obstacleIds = new Integer[] { 3 };
		Integer[] obstacleX = new Integer[] { 225 };
		Integer[] obstacleY = new Integer[] { 300 };

		BaseGameLevel gameLevel = new StartGameLevel();
		gameLevel.setLevel(level);
		gameLevel.setFireflyIds(Arrays.asList(fireflyIds));
		gameLevel.setFireflyX(Arrays.asList(fireflyX));
		gameLevel.setFireflyY(Arrays.asList(fireflyY));
		gameLevel.setPortalIds(Arrays.asList(portalIds));
		gameLevel.setPortalX(Arrays.asList(portalX));
		gameLevel.setPortalY(Arrays.asList(portalY));
		gameLevel.setObstacleIds(Arrays.asList(obstacleIds));
		gameLevel.setObstacleX(Arrays.asList(obstacleX));
		gameLevel.setObstacleY(Arrays.asList(obstacleY));

		dbManager.addGameLevel(gameLevel);
	}

	private void addGameLevel3() {
		int level = 3;

		Integer[] fireflyIds = new Integer[] { 0, 0, 0, 0, 1, 1, 1, 1 };
		Integer[] fireflyX = new Integer[] { 110, 250, 370, 280, 150, 180, 270,
				310 };
		Integer[] fireflyY = new Integer[] { 180, 170, 260, 350, 440, 530, 220,
				410 };
		Integer[] portalIds = new Integer[] { 0, 1 };
		Integer[] portalX = new Integer[] { 0, 380 };
		Integer[] portalY = new Integer[] { 0, 620 };
		Integer[] obstacleIds = new Integer[] { 3 };
		Integer[] obstacleX = new Integer[] { 300 };
		Integer[] obstacleY = new Integer[] { 400 };

		BaseGameLevel gameLevel = new StartGameLevel();
		gameLevel.setLevel(level);
		gameLevel.setFireflyIds(Arrays.asList(fireflyIds));
		gameLevel.setFireflyX(Arrays.asList(fireflyX));
		gameLevel.setFireflyY(Arrays.asList(fireflyY));
		gameLevel.setPortalIds(Arrays.asList(portalIds));
		gameLevel.setPortalX(Arrays.asList(portalX));
		gameLevel.setPortalY(Arrays.asList(portalY));
		gameLevel.setObstacleIds(Arrays.asList(obstacleIds));
		gameLevel.setObstacleX(Arrays.asList(obstacleX));
		gameLevel.setObstacleY(Arrays.asList(obstacleY));

		dbManager.addGameLevel(gameLevel);
	}
}
